package com.lightkits.wms.domain.pickreport.service.impl;

import com.lightkits.common.db.entity.WmExecuteLine;
import com.lightkits.common.db.entity.WmRequestHeader;
import com.lightkits.common.db.entity.WmRequestLine;
import com.lightkits.common.db.entity.event.BdEvent;
import com.lightkits.common.service.impl.CommonTransaction;
import com.lightkits.common.service.impl.WmReqHeaderDBService;
import com.lightkits.common.service.impl.WmReqLineDBService;
import com.lightkits.framework.common.exception.LightKitsBizException;
import com.lightkits.framework.common.model.CheckResult;
import com.lightkits.wms.domain.pickreport.service.PickReportTransactionService;
import com.lightkits.wms.domain.rawmatstorage.repo.WmExecuteLineService;
import com.lightkits.wms.domain.saveonhand.models.OnhandParams;
import com.lightkits.wms.domain.saveonhand.service.UseParamsDomain;
import com.lightkits.wms.dto.onhand.model.OnhandDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * PickReportTransactionServiceImpl
 *
 * @author zhuangwei.zheng@hand-china.com
 * Created on 2019/5/8 19:48
 */
@Service
public class PickReportTransactionServiceImpl implements PickReportTransactionService {

    private final WmReqHeaderDBService reqHeaderDBService;

    private final WmReqLineDBService reqLineDBService;

    private final WmExecuteLineService executeLineService;

    private final UseParamsDomain useParamsDomain;

    @Autowired
    private CommonTransaction commonTransaction;

    @Autowired
    public PickReportTransactionServiceImpl(WmReqHeaderDBService reqHeaderDBService, WmReqLineDBService reqLineDBService, WmExecuteLineService executeLineService, UseParamsDomain useParamsDomain) {
        this.reqHeaderDBService = reqHeaderDBService;
        this.reqLineDBService = reqLineDBService;
        this.executeLineService = executeLineService;
        this.useParamsDomain = useParamsDomain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePickReportHeads(List<WmRequestHeader> requestHeaders) {
        List<WmRequestHeader> addHeadList = new ArrayList<>();
        List<WmRequestHeader> updHeadList = new ArrayList<>();
        requestHeaders.forEach(target -> {
            if (target.getId() == null) {
                addHeadList.add(target);
            } else {
                updHeadList.add(target);
            }
        });
        if (!addHeadList.isEmpty() && !reqHeaderDBService.insertBatch(addHeadList)) {
            throw new LightKitsBizException("Insert wmRequestHead error.");
        }
        if (!updHeadList.isEmpty() && !reqHeaderDBService.updateBatchById(updHeadList)) {
            throw new LightKitsBizException("Update wmRequestHead error.");
        }
        List<WmRequestLine> addLineList = new ArrayList<>();
        List<WmRequestLine> updLineList = new ArrayList<>();
        requestHeaders.forEach(head -> {
            List<Object> objects = head.take();
            if (objects != null) {
                objects.forEach(target -> {
                    WmRequestLine line = (WmRequestLine) target;
                    if (line.getId() == null) {
                        addLineList.add(line);
                        line.setRequestId(head.getId());
                    } else {
                        updLineList.add(line);
                    }
                });
            }
        });
        if (!addLineList.isEmpty() && !reqLineDBService.insertBatch(addLineList)) {
            throw new LightKitsBizException("Insert wmRequestLine error.");
        }
        if (!updLineList.isEmpty() && !reqLineDBService.updateBatchById(updLineList)) {
            throw new LightKitsBizException("Update wmRequestLine error.");
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveWmRequestExecute(List<WmExecuteLine> wmExecuteLines) {
        List<BdEvent> events = new ArrayList<>();
        wmExecuteLines.forEach(wmExecuteLine -> {
            List<Object> objects = wmExecuteLine.take();
            if (objects != null) {
                objects.forEach(target -> {
                    BdEvent event = (BdEvent) target;
                    events.add(event);
                });
            }
        });
        commonTransaction.saveEvents(events);
        List<OnhandDTO> handDtoList = new ArrayList<>();
        wmExecuteLines.forEach(wmExecuteLine -> {
            List<Object> objects = wmExecuteLine.take();
            List<Object> onhandDTOS = wmExecuteLine.take("OnhandDTO");
            OnhandDTO dto = null;
            if (onhandDTOS != null) {
                dto = (OnhandDTO) onhandDTOS.get(0);
            }
            OnhandDTO onhandDTO = dto;
            if (objects != null) {
                objects.forEach(target -> {
                    BdEvent event = (BdEvent) target;
                    wmExecuteLine.setEventId(event.getId());
                    if (onhandDTO != null) {
                        onhandDTO.setParentEventId(event.getId().toString());
                        handDtoList.add(onhandDTO);
                    }
                });
            }
        });
        handDtoList.forEach(target -> {
            CheckResult<String> checkResultRes = new CheckResult<>();
            checkResultRes.setSuccessful(true);
            CheckResult<OnhandParams> checkResult = useParamsDomain.getOnhandParams(target);
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            CheckResult<String> result = useParamsDomain.insertValue(checkResult.getData());
            if (!result.isSuccessful()) {
                throw new LightKitsBizException(result.getMessage());
            }
        });
        if (!wmExecuteLines.isEmpty() && !executeLineService.insertBatch(wmExecuteLines)) {
            throw new LightKitsBizException("Insert WmExecuteLine error.");
        }


    }
}
